package com.ccp.dev.workflow.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ClassDescribe:
 * 流程定义中的节点定义树形以及运行中的人员配置
 *
 * @author :wangcheng
 * Date: 2019-06-18
 */
public class FlowNodeInfo {
    public static final String TYPE_USERTASK = "UserTask";
    public static final String TYPE_SERVICETASK = "ServiceTask";
    public static final String TYPE_SCRIPTTASK = "ScriptTask";
    public static final String TYPE_SENDTASK = "SendTask";
    public static final String TYPE_SUBPROCESS = "SubProcess";
    public static final String TYPE_CALLACTIVITY = "CallActivity";
    public static final String TYPE_START_EVENT = "StartEvent";
    public static final String TYPE_END_EVENT = "EndEvent";
    /**
     * 并行网关，多个执行流并行执行
     */
    public static final String TYPE_PARALLELGATEWAY = "ParallelGateway";
    /**
     * 条件同步网关
     */
    public static final String TYPE_INCLUSIVEGATEWAY = "InclusiveGateway";
    /**
     * 单向网关，只能选择一条执行路径
     */
    public static final String TYPE_EXCLUSIVEGATEWAY = "ExclusiveGateway";

    /**
     * 节点ID
     */
    private String nodeId = null;

    /**
     * 节点名称
     */
    private String nodeName = null;

    /**
     * 值为userTask,subProcess,Gateway等
     */
    private String nodeType = null;

    /**
     * 是否为多实例任务
     */
    private Boolean isMultiInstance = false;

    /**
     * 父节点，用于子流程中的任务节点
     */
    private FlowNodeInfo parentNode = null;

    /**
     * 是否为流程中的第一个节点
     */
    private boolean isFirstNode = false;

    /**
     * 跳转到该节点的条件
     */
    private String condition="";

    /**
     * 树形map
     */
    private Map<String, String> attrMap = new HashMap<>();

    /**
     * 子流程节点
     */
    private Map<String, FlowNodeInfo> subProcessNodes = new HashMap<>();

    /**
     * 前置节点列表
     */
    private List<FlowNodeInfo> preFlowNodesInfo = new ArrayList<>();
    /**
     * 后置节点列表
     */
    private List<FlowNodeInfo> nextFlowNodesInfo = new ArrayList<>();

    /**
     * 当nodeType为subProcess时，存放子流程下的所有任务节点
     */
    private List<FlowNodeInfo> subFlowNodes = new ArrayList<>();

    /**
     * 子流程中的第一个任务节点
     */
    private FlowNodeInfo subFirstNode = null;

    public FlowNodeInfo() {
    }

    public FlowNodeInfo(String nodeId, String nodeName, String nodeType) {
        this.nodeId = nodeId;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
    }

    public FlowNodeInfo(String nodeId, String nodeName, String nodeType, Boolean isMultiInstance, List<FlowNodeInfo> subFlowNodes) {
        this.nodeId = nodeId;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
        this.isMultiInstance = isMultiInstance;
        this.subFlowNodes = subFlowNodes;
    }

    public FlowNodeInfo(String nodeId, String nodeName, String nodeType, Boolean isMultiInstance, FlowNodeInfo parentNode) {
        this.nodeId = nodeId;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
        this.isMultiInstance = isMultiInstance;
        this.parentNode = parentNode;
    }

    public FlowNodeInfo(String nodeId, String nodeName, String nodeType, Boolean isMultiInstance) {
        this.nodeId = nodeId;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
        this.isMultiInstance = isMultiInstance;
    }

    public FlowNodeInfo(String nodeId, String nodeName, String nodeType, List<FlowNodeInfo> subFlowNodes) {
        this.nodeId = nodeId;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
        this.subFlowNodes = subFlowNodes;
    }

    public String getNodeId() {
        return nodeId;
    }

    public void setNodeId(String nodeId) {
        this.nodeId = nodeId;
    }

    public String getNodeName() {
        return nodeName;
    }

    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

    public String getNodeType() {
        return nodeType;
    }

    public void setNodeType(String nodeType) {
        this.nodeType = nodeType;
    }

    public Boolean getIsMultiInstance() {
        return isMultiInstance;
    }

    public void setIsMultiInstance(Boolean isMultiInstance) {
        this.isMultiInstance = isMultiInstance;
    }

    public FlowNodeInfo getParentNode() {
        return parentNode;
    }

    public void setParentNode(FlowNodeInfo parentNode) {
        this.parentNode = parentNode;
    }

    public Map<String, FlowNodeInfo> getSubProcessNodes() {
        return subProcessNodes;
    }

    public void setSubProcessNodes(Map<String, FlowNodeInfo> subProcessNodes) {
        this.subProcessNodes = subProcessNodes;
    }

    public List<FlowNodeInfo> getPreFlowNodesInfo() {
        return preFlowNodesInfo;
    }

    public void setPreFlowNodesInfo(List<FlowNodeInfo> preFlowNodesInfo) {
        this.preFlowNodesInfo = preFlowNodesInfo;
    }

    public List<FlowNodeInfo> getNextFlowNodesInfo() {
        return nextFlowNodesInfo;
    }

    public void setNextFlowNodesInfo(List<FlowNodeInfo> nextFlowNodesInfo) {
        this.nextFlowNodesInfo = nextFlowNodesInfo;
    }

    public List<FlowNodeInfo> getSubFlowNodes() {
        return subFlowNodes;
    }

    public void setSubFlowNodes(List<FlowNodeInfo> subFlowNodes) {
        this.subFlowNodes = subFlowNodes;
    }

    public FlowNodeInfo getSubFirstNode() {
        return subFirstNode;
    }

    public void setSubFirstNode(FlowNodeInfo subFirstNode) {
        this.subFirstNode = subFirstNode;
    }

    public String getCondition() {
        return condition;
    }

    public void setCondition(String condition) {
        this.condition = condition;
    }

    /**
     * 是否是子流程
     * @return true or false
     */
    public boolean getIsSubProcess() {
        return "subProcess".equalsIgnoreCase(this.nodeType);
    }

    /**
     * 是否是外部子流程
     * @return true or false
     */
    public boolean getIsCallActivity() {
        return "callActivity".equalsIgnoreCase(this.nodeType);
    }

    /**
     * 是否是会签节点
     */
    public boolean getIsSignNode() {
        if (this.nodeType.equalsIgnoreCase(TYPE_USERTASK) && getIsMultiInstance()) {
            return true;
        }
        return false;
    }

    /**
     * 是否是第一个节点
     */
    public boolean getIsFirstNode() {
        List<FlowNodeInfo> preFlowNodesInfo = this.getPreFlowNodesInfo();
        if (preFlowNodesInfo != null) {
            for (FlowNodeInfo node : preFlowNodesInfo) {
                if (node.getNodeType().equalsIgnoreCase(TYPE_START_EVENT)) {
                    return true;
                }
            }
        }
        return false;
    }

    public void setIsFirstNode(boolean isFirstNode) {
        this.isFirstNode = isFirstNode;
    }

    /**
     * 设置树形
     * @param name 属性名称
     * @param value 属性值
     */
    public void setAttribute(String name, String value) {
        this.attrMap.put(name, value);
    }

    /**
     * 获取属性
     * @param name 属性名
     * @return 属性值
     */
    public String getAttribute(String name) {
        if (this.attrMap.containsKey(name)) {
            return this.attrMap.get(name);
        }
        return "";
    }
}
